#ifndef __MEDIAFS_CONVERTERS_H__
#define __MEDIAFS_CONVERTERS_H__

#include <sys/types.h>

struct mediafs_decoder_ctx {
	size_t		ctx_size;
	struct mediafs_decoder *decoder;

	char const	*stream_contents;
	size_t		stream_size;
};

struct mediafs_decoder_stat {
	uint64_t len_samples;
	uint32_t samples_per_sec;
	short bits_per_sample;
	short num_channels;
};

typedef struct mediafs_decoder_ctx *(*mediafs_decoder_ctx_open_func)(char const *_stream_contents, size_t _stream_size);
typedef void (*mediafs_decoder_ctx_close_func)(struct mediafs_decoder_ctx *_ctx);

typedef int (*mediafs_decoder_ctx_get_stat_func)(struct mediafs_decoder_ctx *_ctx, struct mediafs_decoder_stat *_stat);
typedef int (*mediafs_decoder_ctx_decode_func)(struct mediafs_decoder_ctx *_ctx, uint64_t _samples_from, uint64_t _samples_duration, char *_buffer);

struct mediafs_decoder {
	char const *name;

	mediafs_decoder_ctx_open_func ctx_open_func;
	mediafs_decoder_ctx_close_func ctx_close_func;
	mediafs_decoder_ctx_get_stat_func ctx_get_stat_func;
	mediafs_decoder_ctx_decode_func ctx_decode_func;
};

extern struct mediafs_decoder_ctx *mediafs_decoder_open(struct mediafs_decoder *_decoder, char const *_stream_contents, size_t _stream_size);
extern void mediafs_decoder_close(struct mediafs_decoder_ctx *_ctx);
extern int mediafs_decoder_get_stat(struct mediafs_decoder_ctx *_ctx, struct mediafs_decoder_stat *_stat);
extern int mediafs_decoder_decode(struct mediafs_decoder_ctx  *_ctx, uint64_t _samples_from, uint64_t _samples_duration, char *_buffer);

struct mediafs_encoder_params {
	size_t params_size;
	struct mediafs_decoder_stat source_stat;
};

struct mediafs_encoder_ctx {
	size_t ctx_size;
	struct mediafs_encoder *encoder;
	struct mediafs_encoder_params *params;
};

struct mediafs_encoder_stat {
	uint64_t frames_number;
	uint32_t samples_per_frame;
	size_t frame_size;
};

typedef struct mediafs_encoder_ctx *(*mediafs_encoder_ctx_open_func)(struct mediafs_encoder_params *_params);
typedef void (*mediafs_encoder_ctx_close_func)(struct mediafs_encoder_ctx *_ctx);

typedef int (*mediafs_encoder_ctx_get_stat)(struct mediafs_encoder_ctx *_ctx, struct mediafs_encoder_stat *_stat);
typedef int (*mediafs_encoder_ctx_write_header)(struct mediafs_encoder_ctx *_ctx, char *buffer, size_t *buffer_size);
typedef int (*mediafs_encoder_ctx_encode)(struct mediafs_encoder_ctx *_ctx, uint64_t _frame_offset, uint64_t frames_duration, char *_src_buffer,
	char *_dest_buffer, size_t *_dest_buffer_size);

struct mediafs_encoder {
	char *name;
	
	mediafs_encoder_ctx_open_func ctx_open_func;
	mediafs_encoder_ctx_close_func ctx_close_func;
	mediafs_encoder_ctx_get_stat ctx_get_stat_func;
	mediafs_encoder_ctx_write_header ctx_write_header_func;
	mediafs_encoder_ctx_encode ctx_encode_func;
};

extern struct mediafs_encoder_ctx *mediafs_encoder_open(struct mediafs_encoder *_encoder, struct mediafs_encoder_params *_params);
extern void mediafs_encoder_close(struct mediafs_encoder_ctx *_ctx);

extern int mediafs_encoder_get_stat(struct mediafs_encoder_ctx *_ctx, struct mediafs_encoder_stat *_stat);
extern int mediafs_encoder_write_header(struct mediafs_encoder_ctx *_ctx, char *_buffer, size_t *_buffer_size);
extern int mediafs_encoder_encode(struct mediafs_encoder_ctx *_ctx, uint64_t _frames_offset, uint64_t _frames_duration,
	char *_src_buffer, char *_dest_buffer, size_t *_dest_buffer_size);


#endif

